﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections;
using Microsoft.Research.DynamicDataDisplay.DataSources;
using Microsoft.Research.DynamicDataDisplay;
using Microsoft.Research.DynamicDataDisplay.Common;
using Microsoft.Research.DynamicDataDisplay.Charts;
using System.Windows.Threading;
using System.Text.RegularExpressions;




namespace WpfApplicationWithGrid
{
    /// <summary>
    /// Interaction logic for newConfiguration.xaml
    /// </summary>
    public partial class Configuration : Window
    {
        private Parameter para = Parameter.getParameter();
        private WorkFlow workflow = WorkFlow.getWorkFlow();
        Regex regexD = new Regex(@"^[0-9,-\.]+$");
        Regex regexI = new Regex(@"^[0-9,-]+$"); 
        private string errorMsg = null;
        readonly DispatcherTimer timer = new DispatcherTimer();
        Communication c;
        public Configuration(string account_name)
        {
            InitializeComponent();

            c = Communication.getCommunication();
            c.getConfig(null);
            timer.Interval = TimeSpan.FromMilliseconds(para.UpdateFreq);
            timer.Tick += AnimatedPlot_Timer;
            timer.IsEnabled = true;
            //below 2 are going to be within a time thread
           

            populateForm();
            account_label.Content = "Welcome " + account_name;



            DataVisualize.init();
            DataRect datarect = new DataRect(new Point(0, 0), new Point(30, 1));
            this.chart_hit.Visible = datarect;
            this.chart_success.Visible = datarect;
            this.chart_avg.Visible = new DataRect(new Point(0, 0), new Point(30, 2));
            this.chart_success.AddLineGraph(new CompositeDataSource(DataVisualize.xSrc, DataVisualize.successSrc),
            new Pen(Brushes.Black, 3),
                new PenDescription("Success Ratio"));

            this.chart_hit.AddLineGraph(new CompositeDataSource(DataVisualize.xSrc, DataVisualize.hitSrc),
            new Pen(Brushes.DarkOrange, 3),
            new PenDescription("Hit Ratio"));

            this.chart_avg.AddLineGraph(new CompositeDataSource(DataVisualize.xSrc, DataVisualize.avgSrc),
            new Pen(Brushes.Green, 3),
            new PenDescription("Avg Processing Time"));


        }

        private void AnimatedPlot_Timer(object sender, EventArgs e)
        {
            try
            {
                c.getFlow();
                this.Label_status.Content = "Server is normal";
            }
            catch (Exception ex)
            {
                this.Label_status.Content = ex.Message;
                this.timer.IsEnabled = false;
            }
            
            this.updateUsers();
            TimeSpan.FromMilliseconds(para.UpdateFreq);
        }

        public void populateForm()
        {
            sizeNum.Value = para.CacheSize;
            comboBox_method.SelectedIndex = ConvertCacheMethod(para.CacheMethod);
            ConvertCacheCont(para.Hist, para.Stock_25, para.Realtime);
            updateUrlList();
            textBox_freq.Text = para.UpdateFreq.ToString();
            textBox_timeduration.Text = para.TimeDuration.ToString();
            if (para.Realtime > 0)
            {
                textBox_analyticaldata.IsEnabled = true;
                textBox_analyticaldata.Text = para.Realtime.ToString();
            }
            else
            {
                textBox_analyticaldata.IsEnabled = false;
            }
            
            
        }

        public void updateUsers()
        {
            workflow = WorkFlow.getWorkFlow();
            this.Label_broker_count.Content = workflow.Broker;
            this.Label_mobileuser_count.Content = workflow.MobileUser;
            this.Label_webuser_count.Content = workflow.WebUser;
        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {

        }

        public void ButtonOK_Click(object sender, RoutedEventArgs e)
        {
            SubmitErrorMsg();
            if (errorMsg != null)
                return;
           
            Parameter param = Parameter.getParameter();

            param.InputStream = new ArrayList(listBox_url.Items);
            param.UpdateFreq = double.Parse(textBox_freq.Text);
            param.TimeDuration = int.Parse(textBox_timeduration.Text);
            param.CacheSize = (int)sizeNum.Value;
            param.CacheMethod = SaveCacheMethod(comboBox_method.SelectedIndex);
            setCacheCont();

            if (checkBox_others.IsChecked == true)
            {
                param.Realtime = int.Parse(textBox_analyticaldata.Text);
            }

            Communication comm = Communication.getCommunication();

            try
            {
                if (!comm.update())
                {
                    MessageBox.Show("System Update Failed ! Please Update Again.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    populateForm();
                }
                else
                    MessageBox.Show("System Update Succeeded", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }

            /*
            
            if (ackMsg == true)
            {
                paraFinal = para;// donnot know if it is ok use copy object!!!!!!!!!!!!!!!!!!!!!!
                //popup successful msg
            }

            if (ackMsg == false)
            {
                //popup failure msg
                ButtonReset();
            }
             */
        }
           

        public void ButtonReset_Click(object sender, RoutedEventArgs e)
        {
            sizeNum.Value = para.CacheSize;
            comboBox_method.SelectedIndex = ConvertCacheMethod(para.CacheMethod);
            ConvertCacheCont(para.Hist, para.Stock_25, para.Realtime);
            updateUrlList();
            textBox_freq.Text = para.UpdateFreq.ToString();
            textBox_timeduration.Text = para.TimeDuration.ToString();

            if (para.Realtime > 0)
            {
                textBox_analyticaldata.IsEnabled = true;
                textBox_analyticaldata.Text = para.Realtime.ToString();
            }
            else
            {
                textBox_analyticaldata.IsEnabled = false;
            }

        }

        public void EnableTextbox(object sender, RoutedEventArgs e)
        {
            if (checkBox_others.IsChecked == true)
                textBox_analyticaldata.IsEnabled = true;
            else
            {
                textBox_analyticaldata.IsEnabled = false;
                //textBox_analyticaldata.Text = null;
            }
        }

        public string SaveCacheMethod(int index)
        {
            if (index == 1)
                return "First In First Out";
            if (index == 2)
                return "Least Recently Used";
            else
                return "Least Frequently Used";
        }
      
        public int ConvertCacheMethod(string c)
        {
            if(c == "First In First Out")
                    return 1;
            if(c == "Least Recently Used")
                    return 2;
            if(c == "Least Frequently Used")
                    return 3;
            else
                return 0;
        }
        
        public void setCacheCont()
        {
            
            para.Hist = (checkBox1.IsChecked == true) ? 1 : -1;
            para.Stock_25 = (checkBox2.IsChecked == true) ? 1 : -1;
            para.Realtime = (checkBox_others.IsChecked == true) ? 1 : -1;
        }
        
        public void ConvertCacheCont(int hist, int stock_25, int realtime)
        {
            checkBox1.IsChecked = (hist > 0) ? true:false;
            checkBox2.IsChecked = (stock_25 > 0) ? true : false;
            checkBox_others.IsChecked = (realtime > 0) ? true : false;
        }

        //validation metohds

        public bool validateURL()
        {
            ItemCollection ic = listBox_url.Items;
         
            foreach (Object i in ic)
            {
                string temp = ((string) i).Substring(0, 7);

                if (temp.CompareTo("http://") != 0)
                    return false;
            }
            return true;
        }

        public bool validateUpdateFreq(string i)
        {
            if (regexD.IsMatch(i))
            {
                if (double.Parse(i) < 1)
                    return false;
                else
                    return true;
            }
            else
                return false;
        }

        public bool validateTimeDuration(string i)
        {
            if (regexI.IsMatch(i))
            {
                if (int.Parse(i) < 300)
                    return false;
                else
                    return true;
            }
            else
                return false;
        }

        public bool validateCacheMethod(int s)
        {
            if (s == 0)
                return false;
            else
                return true;
        }

        private void button_Add_Click(object sender, RoutedEventArgs e)
        {
            var dialog = new Dialog(true, "");
            dialog.Top = 260;
            dialog.Left = 600;
            if (dialog.ShowDialog() == true)
            {
                this.listBox_url.Items.Add(dialog.getURL());
            }
        }

        private void button_Delete_Click(object sender, RoutedEventArgs e)
        {
            if (this.listBox_url.SelectedIndex != -1)
            {
                MessageBoxResult result = MessageBox.Show("Do you really want to delete", "Question", MessageBoxButton.YesNo, MessageBoxImage.Question);
                if (result == MessageBoxResult.Yes)
                {

                    this.listBox_url.Items.RemoveAt(this.listBox_url.SelectedIndex);

                }
            }
            else
            {
                MessageBox.Show("No URL is selected!", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning);
            }

        }

        private void button_Edit_Click(object sender, RoutedEventArgs e)
        {
            if (this.listBox_url.SelectedIndex != -1)
            {
                var dialog = new Dialog(false, this.listBox_url.SelectedItem.ToString());
                dialog.Top = 260;
                dialog.Left = 600;
                if (dialog.ShowDialog() == true)
                {
                    int i = this.listBox_url.SelectedIndex;
                    this.listBox_url.Items.RemoveAt(i);
                    this.listBox_url.Items.Insert(i, dialog.getURL());
                }

            }
            else
            {
                MessageBox.Show("No URL is selected!", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
            
        }


        
        public bool validateSpecNum(string i)
        {
            if (i != null)
            {
                if (int.Parse(i) < 1 || int.Parse(i) > 500 || regexI.IsMatch(i) == false)
                    return false;
                else
                    return true;
            }
            else
                return true;
        }

        public void updateUrlList()
        {
            this.listBox_url.Items.Clear();
            foreach (Object value in para.InputStream)
            {
               
                this.listBox_url.Items.Add(value.ToString().Substring(1,value.ToString().Length-2));
            }
        }

        public void SubmitErrorMsg()
        {
            errorMsg = null;

            if (validateURL() == false)
            {
                errorMsg += "URL should start with 'http://'.\n";
            }

            if (validateUpdateFreq(textBox_freq.Text) == false)
            {
                textBox_freq.Text = "1";
                errorMsg += "The value of Update Frequency should be a number greater than 1.0 milliseconds.\n";
                
            }

            if (validateTimeDuration(textBox_timeduration.Text) == false)
            {
                errorMsg += "The value of Time Duration should be an integer greater than 300 seconds.\n";
            }

            if (validateCacheMethod(comboBox_method.SelectedIndex) == false)
            {
                errorMsg += "Select a Cache Method.\n";
            }

            if (checkBox_others.IsChecked == true && validateSpecNum(textBox_analyticaldata.Text) == false)
            {
                errorMsg += "The number of stocks should be in the range from 1 to 500.\n";
            }

            if (errorMsg != null)
            {
                MessageBox.Show(errorMsg, "Error", MessageBoxButton.OK, MessageBoxImage.Error); 
            }
        }

        private void button_conflogout_Click(object sender, RoutedEventArgs e)
        {
            
            MainWindow newMainWindow = new MainWindow();
            newMainWindow.Show();
            this.Close();
        }



    }
   
}
